/*! @file binaryviewwidget.cpp
 * @brief Implements BinaryViewWidget Class
 * @date 08.10.2012
 */

#include "binaryviewwidget.h"

#include <QFile>

/**
 * @brief BinaryViewWidget ctor
 *
 * @fn BinaryViewWidget::BinaryViewWidget
 * @param i int: tabIndex
 * @param lpath QString: path and filename to open
 * @param parent
 */
BinaryViewWidget::BinaryViewWidget(int i, QString lpath, QWidget *parent) :
    QWidget(parent)
{
    setupUi(this);
    progressBar->hide();

    idx = i;
    file = new QFile(lpath);
    bytecount = 0;
    linecount = 0;
    bytesperline = spinBox->value();
    filterEmpty = filterEmptyLinesCheckBox->checkState();
    QTextCharFormat fmt = textBrowser->currentCharFormat();
    fmt.setFontFamily("curier");
    fmt.setFontFixedPitch(true);
    textBrowser->setCurrentCharFormat(fmt);
    textBrowser->setLineWrapMode(QPlainTextEdit::NoWrap);


    // other connections
    connect (cancelPushButton, SIGNAL(clicked()), this, SLOT(on_cancelPushButtonClicked()));
    connect (closePushButton, SIGNAL(clicked()), this, SLOT(closeTab()));
    connect (bytesButton, SIGNAL(clicked()), this, SLOT(setBytesWidth()));
    connect (filterEmptyLinesCheckBox, SIGNAL(stateChanged(int)),
            this, SLOT(filterEmptyLines()));
}

/**
 * @brief closes file and tab
 *
 * @fn BinaryViewWidget::closeTab
 */
void BinaryViewWidget::closeTab() {
    file->close();
    Q_EMIT closeMe(idx);
}

void BinaryViewWidget::filterEmptyLines() {
    if (filterEmptyLinesCheckBox->checkState() == Qt::Checked)
        filterEmpty = true;
    else
        filterEmpty = false;

    parseFile();
}

void BinaryViewWidget::on_cancelPushButtonClicked() {
    qDebug() << "BinaryViewWidget\t| on_cancelPushButtonClicked() - terminating";
    worker->terminate();
    //while(!worker->isFinished()) {}
    //if(!worker->isRunning())
        Q_EMIT parsingCanceled();
}

/**
 * @brief opens file
 *
 * @fn BinaryViewWidget::openFile
 * @param f
 * @return int: 0 on success
 */
int BinaryViewWidget::openFile() {
    if (!file->open(QIODevice::ReadOnly)) {
        qDebug() << "BinaryViewWidget\t| openFile() error!";
        return -99;
    }
    else {
        qDebug() << "BinaryViewWidget\t| openFile() Emitting fileOpened()!";
        Q_EMIT fileOpened();
        return 0;
    }
}

/**
 * @brief
 *
 * @fn BinaryViewWidget::parseFile
 * @return int
 */
int BinaryViewWidget::parseFile() {
    qDebug() << "BinaryViewWidget\t| parseFile() called:" << file->fileName() << file->size() ;

    cancelPushButton->setEnabled(true);
    t.start();

    QThread* thread = new QThread;
    worker = new ParseThread(file, this);

    //connect (worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
    connect (thread, SIGNAL(started()), worker, SLOT(process()));
    connect (worker, SIGNAL(finished()), thread, SLOT(quit()));
    connect (worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect (thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    connect (worker, SIGNAL(finished()), this, SLOT(parsingFinished()));
    connect (worker, SIGNAL(writeMe(QString)), this, SLOT(writePage(QString)));
    connect (worker, SIGNAL(progressSetValue(int)), this, SLOT(updateProgressBar(int)));


    progressBar->setEnabled(true);
    progressBar->setMinimum(0);
    progressBar->setMaximum(file->size());
    progressBar->show();

    QFont font("Monospace");
    font.setStyleHint(QFont::TypeWriter);

    thread->start();

    return 0;
}

/**
 * @brief
 *
 * @fn BinaryViewWidget::parsingFinished
 */
void BinaryViewWidget::parsingFinished() {
    Q_EMIT fileParsed();
    //Q_EMIT writeMe(finalbuffer);
    qDebug () << "BinaryViewWidget\t|parseThread finished!";
}

/**
 * @brief
 *
 * @fn BinaryViewWidget::setBytesWidth
 */
void BinaryViewWidget::setBytesWidth() {
    textBrowser->clear();
    if(bytesperline != spinBox->value()) {
        bytesperline = spinBox->value();
        parseFile();
    }
    return;
}

/**
 * @brief
 *
 * @fn BinaryViewWidget::updateProgressBar
 * @param byte
 */
void BinaryViewWidget::updateProgressBar(int byte) {
    qApp->processEvents();
    progressBar->setValue(byte);
    progressBar->update();
}

/**
 * @brief
 *
 * @fn BinaryViewWidget::writePage
 * @param page
 */
void BinaryViewWidget::writePage(QString page) {
    qDebug() << "BinaryViewWidget\t| writePage recieved";
    textBrowser->setPlainText(page);
    textBrowser->update();

    parsetimeLabel->setText(QString::number(t.elapsed()) + " ms");

    qApp->processEvents();
    progressBar->hide();
    cancelPushButton->setEnabled(false);
}
